/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package recognizer.neuron;

import java.util.Random;

/**
 * Искусственный нейрон
 * @author Кирилл Чикалин
 */
public class Neuron {
    /**
     * Имя нейрона
     */
    private String name = "";
    /**
     * Входные сигналы
     */
    private boolean[] inputSignals;
    /**
     * Весовые коэффициенты
     */
    private double[] weights;
    /**
     * Количество входных сигналов
     */
    private int numberOfInputs = 0;
    /**
     * Порог чувствительности нейрона
     */
    private double threshold;
    /**
     * Взвешенная сумма входных сигналов
     */
    private double  weighedSum = 0;
    /**
     * Выходной сигнал
     */
    private boolean state = false;
    /**
     * Конструктор
     * @param numberOfInputs Число входных сигналов
     */
    public Neuron(int numberOfInputs, String name) {
        this.numberOfInputs = numberOfInputs;
        inputSignals = new boolean[numberOfInputs];
        weights = new double[numberOfInputs];
        this.name = name;
        
        Random random = new Random();
        for (int i = 0; i < numberOfInputs; i++) {
            weights[i] = random.nextDouble();
        }
        // Устанавливаем случайное пороговое значение
        threshold = random.nextDouble();
    }
    /**
     * Вычисление состояния нейрона
     */
    private void stateProcessing() {
        weighedSum = 0;
        for(int i = 0; i < numberOfInputs; i++) {
            weighedSum += weights[i] *  (inputSignals[i] ? 1.0d : 0.0d);
        }
        state = weighedSum >= threshold;
    }
    /**
     * Получить состояние нейрона
     * @return Состояние нейрона
     */
    public boolean getState() {
        return state;
    }
    /**
     * Установить входные сигналы
     * @param inputSignals Входные сигналы
     */
    public void setInputSignals(boolean[] inputSignals) {
        this.inputSignals = inputSignals;
        stateProcessing();
    }      
    /**
     * Получение массива весовых коэффициентов
     */
    public double[] getWeights() {
        return weights;
    }

    /**
     * Установка весовых коэффициентов
     * @param inputSignals Весовые коэффициенты
     */
    public void setWeights(double[] weights) {
        this.weights = weights;
    }
  
    /**
     * Получение значения i-го весового коэффициента
     * @param i Номер коэффициента
     * @return i-й весовой коэффициент
     */
    public double getWeight(int i) {
        return weights[i];
    }
    
    /**
     * Установка значения i-го весового коэффициента
     * @param i Номер коэффициента
     * @param weight Значение весового коэффициента
     */
    public void setWeight(int i, double weight) {
        weights[i] = weight;
    }
      
    /**
     * Установка порога чувствительности
     * @param threshold Порог чувствительности
     */
    public void setThreshold(double threshold) {
        this.threshold = threshold;
    }
    
    /**
     * Получение порога чувствительности
     */
    public double getThreshold() {
        return threshold;
    }
    
    /**
     * Получить взвешенную сумму
     * @return Взвешенная сумма
     */
    public double getWeighedSum() {
        return weighedSum;
    }
    
    /**
     * Получить имя нейрона
     * @return Имя нейрона
     */
    public String getName() {
        return name;
    }
}
